﻿using UnityEngine;

namespace Yoozoo.Extension
{
    public static class RectTransformEx
    {
        /// <summary>
        /// Converts RectTransform.rect's local coordinates to world space
        /// Usage example RectTransformExt.GetWorldRect(myRect, Vector2.one);
        /// </summary>
        /// <returns>The world rect.</returns>
        /// <param name="rt">RectangleTransform we want to convert to world coordinates.</param>
        /// <param name="scale">Optional scale pulled from the CanvasScaler. Default to using Vector2.one.</param>
        public static Rect GetWorldRect2(this RectTransform rt, Vector2 scale)
        {
            // Convert the rectangle to world corners and grab the top left
            Vector3[] corners = new Vector3[4];
            rt.GetWorldCorners(corners);
            Vector3 topLeft = corners[0];

            // Rescale the size appropriately based on the current Canvas scale
            Vector2 scaledSize = new Vector2(scale.x * rt.rect.size.x, scale.y * rt.rect.size.y);

            return new Rect(topLeft, scaledSize);
        }

        public static Rect GetWorldRect(this RectTransform rt)
        {
            Vector3[] corners = new Vector3[4];
            rt.GetWorldCorners(corners);
            Vector3 min = corners[0];
            Vector3 max = corners[2];
            return new Rect(min, (max - min));
        }

        public static void AddAnchoredPositionX(this RectTransform rt, float x)
        {
            var v3 = rt.anchoredPosition;
            v3.x += x;
            rt.anchoredPosition = v3;
        }
    }

    public static class TransformEx
    {
        public static void SetPositionX(this Transform transform, float x)
        {
            var v3             = transform.position;
            v3.x               = x;
            transform.position = v3;
        }


        public static void SetPositionY(this Transform transform, float y)
        {
            var v3             = transform.position;
            v3.y               = y;
            transform.position = v3;
        }


        public static void SetPositionZ(this Transform transform, float z)
        {
            var v3             = transform.position;
            v3.z               = z;
            transform.position = v3;
        }


        public static void SetPositionXY(this Transform transform, float x, float y)
        {
            transform.position = new Vector3(x, y, transform.position.z);
        }


        public static void SetPositionXY(this Transform transform, in Vector2 v2)
        {
            transform.position = new Vector3(v2.x, v2.y, transform.position.z);
        }


        public static void SetPositionXY(this Transform transform, float value)
        {
            transform.position = new Vector3(value, value, transform.position.z);
        }


        public static void SetPositionXY(this Transform transform, Transform transform2)
        {
            var v3             = transform2.position;
            v3.z               = transform.position.z;
            transform.position = v3;
        }


        public static void SetPosition(this Transform transform, float value)
        {
            transform.position = new Vector3(value, value, value);
        }


        public static void SetRelativePositionX(this Transform transform, float x)
        {
            var v3             = transform.position;
            v3.x              += x;
            transform.position = v3;
        }


        public static void SetRelativePositionY(this Transform transform, float y)
        {
            var v3             = transform.position;
            v3.y              += y;
            transform.position = v3;
        }


        public static void SetRelativePositionZ(this Transform transform, float z)
        {
            var v3             = transform.position;
            v3.z              += z;
            transform.position = v3;
        }


        public static void SetRelativePositionXY(this Transform transform, float x, float y)
        {
            var v3              = transform.position;
            v3.x               += x;
            v3.y               += y;
            transform.position  = v3;
        }


        public static void SetRelativePositionXY(this Transform transform, in Vector2 v2)
        {
            var v3              = transform.position;
            v3.x               += v2.x;
            v3.y               += v2.y;
            transform.position  = v3;
        }


        public static void SetRelativePositionXY(this Transform transform, float value)
        {
            var v3              = transform.position;
            v3.x               += value;
            v3.y               += value;
            transform.position  = v3;
        }


        public static void SetRelativePositionXY(this Transform transform, Transform transform2)
        {
            var v3             = transform .position;
            var v23            = transform2.position;
            v3.x              += v23.x;
            v3.y              += v23.y;
            transform.position = v3;
        }


        public static void SetRelativePosition(this Transform transform, float value)
        {
            transform.position += new Vector3(value, value, value);
        }


        public static void SetLocalPositionX(this Transform transform, float x)
        {
            var v3                  = transform.localPosition;
            v3.x                    = x;
            transform.localPosition = v3;
        }


        public static void SetLocalPositionY(this Transform transform, float y)
        {
            var v3                  = transform.localPosition;
            v3.y                    = y;
            transform.localPosition = v3;
        }


        public static void SetLocalPositionZ(this Transform transform, float z)
        {
            var v3                  = transform.localPosition;
            v3.z                    = z;
            transform.localPosition = v3;
        }


        public static void SetLocalPositionXY(this Transform transform, float x, float y)
        {
            transform.localPosition = new Vector3(x, y, transform.localPosition.z);
        }


        public static void SetLocalPositionXY(this Transform transform, in Vector2 v2)
        {
            transform.localPosition = new Vector3(v2.x, v2.y, transform.localPosition.z);
        }


        public static void SetLocalPositionXY(this Transform transform, float value)
        {
            transform.localPosition = new Vector3(value, value, transform.localPosition.z);
        }


        public static void SetLocalPositionXY(this Transform transform, Transform transform2)
        {
            var v3                  = transform2.localPosition;
            v3.z                    = transform. localPosition.z;
            transform.localPosition = v3;
        }


        public static void SetLocalPosition(this Transform transform, float value)
        {
            transform.localPosition = new Vector3(value, value, value);
        }


        public static void SetRelativeLocalPositionX(this Transform transform, float x)
        {
            var v3                  = transform.localPosition;
            v3.x                   += x;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPositionY(this Transform transform, float y)
        {
            var v3                  = transform.localPosition;
            v3.y                   += y;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPositionZ(this Transform transform, float z)
        {
            var v3                  = transform.localPosition;
            v3.z                   += z;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPositionXY(this Transform transform, float x, float y)
        {
            var v3                  = transform.localPosition;
            v3.x                   += x;
            v3.y                   += y;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPositionXY(this Transform transform, in Vector2 v2)
        {
            var v3                  = transform.localPosition;
            v3.x                   += v2.x;
            v3.y                   += v2.y;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPositionXY(this Transform transform, float value)
        {
            var v3                  = transform.localPosition;
            v3.x                   += value;
            v3.y                   += value;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPositionXY(this Transform transform, Transform transform2)
        {
            var v3                  = transform. localPosition;
            var v23                 = transform2.localPosition;
            v3.x                   += v23.x;
            v3.y                   += v23.y;
            transform.localPosition = v3;
        }


        public static void SetRelativeLocalPosition(this Transform transform, float value)
        {
            transform.localPosition += new Vector3(value, value, value);
        }


        public static void SetScaleX(this Transform transform, float x)
        {
            var v3               = transform.localScale;
            v3.x                 = x;
            transform.localScale = v3;
        }


        public static void SetScaleY(this Transform transform, float y)
        {
            var v3               = transform.localScale;
            v3.y                 = y;
            transform.localScale = v3;
        }


        public static void SetScaleZ(this Transform transform, float z)
        {
            var v3               = transform.localScale;
            v3.z                 = z;
            transform.localScale = v3;
        }


        public static void SetScaleXY(this Transform transform, float x, float y)
        {
            transform.localScale = new Vector3(x, y, transform.localScale.z);
        }


        public static void SetScaleXY(this Transform transform, in Vector2 v2)
        {
            transform.localScale = new Vector3(v2.x, v2.y, transform.localScale.z);
        }


        public static void SetScaleXY(this Transform transform, float value)
        {
            transform.localScale = new Vector3(value, value, transform.localScale.z);
        }


        public static void SetScaleXY(this Transform transform, Transform transform2)
        {
            var v3               = transform2.localScale;
            v3.z                 = transform. localScale.z;
            transform.localScale = v3;
        }


        public static void SetScale(this Transform transform, float value)
        {
            transform.localScale = new Vector3(value, value, value);
        }


        public static void SetRelativeScaleX(this Transform transform, float x)
        {
            var v3               = transform.localScale;
            v3.x                += x;
            transform.localScale = v3;
        }


        public static void SetRelativeScaleY(this Transform transform, float y)
        {
            var v3               = transform.localScale;
            v3.y                += y;
            transform.localScale = v3;
        }


        public static void SetRelativeScaleZ(this Transform transform, float z)
        {
            var v3               = transform.localScale;
            v3.z                += z;
            transform.localScale = v3;
        }


        public static void SetRelativeScaleXY(this Transform transform, float x, float y)
        {
            var v3               = transform.localScale;
            v3.x                += x;
            v3.y                += y;
            transform.localScale = v3;
        }


        public static void SetRelativeScaleXY(this Transform transform, in Vector2 v2)
        {
            var v3               = transform.localScale;
            v3.x                += v2.x;
            v3.y                += v2.y;
            transform.localScale = v3;
        }


        public static void SetRelativeScaleXY(this Transform transform, float value)
        {
            var v3               = transform.localScale;
            v3.x                += value;
            v3.y                += value;
            transform.localScale = v3;
        }


        public static void SetRelativeScaleXY(this Transform transform, Transform transform2)
        {
            var v3               = transform. localScale;
            var v23              = transform2.localScale;
            v3.x                += v23.x;
            v3.y                += v23.y;
            transform.localScale = v3;
        }


        public static void SetRelativeScale(this Transform transform, float value)
        {
            transform.localScale += new Vector3(value, value, value);
        }


        public static void SetRotationX(this Transform transform, float x)
        {
            var v3                = transform.eulerAngles;
            v3.x                  = x;
            transform.eulerAngles = v3;
        }


        public static void SetRotationY(this Transform transform, float y)
        {
            var v3                = transform.eulerAngles;
            v3.y                  = y;
            transform.eulerAngles = v3;
        }


        public static void SetRotationZ(this Transform transform, float z)
        {
            var v3                = transform.eulerAngles;
            v3.z                  = z;
            transform.eulerAngles = v3;
        }


        public static void SetRelativeRotationX(this Transform transform, float x)
        {
            var v3                = transform.eulerAngles;
            v3.x                 += x;
            transform.eulerAngles = v3;
        }


        public static void SetRelativeRotationY(this Transform transform, float y)
        {
            var v3                = transform.eulerAngles;
            v3.y                 += y;
            transform.eulerAngles = v3;
        }


        public static void SetRelativeRotationZ(this Transform transform, float z)
        {
            var v3                = transform.eulerAngles;
            v3.z                 += z;
            transform.eulerAngles = v3;
        }


        public static void SetLocalRotationX(this Transform transform, float x)
        {
            var v3                     = transform.localEulerAngles;
            v3.x                       = x;
            transform.localEulerAngles = v3;
        }


        public static void SetLocalRotationY(this Transform transform, float y)
        {
            var v3                     = transform.localEulerAngles;
            v3.y                       = y;
            transform.localEulerAngles = v3;
        }


        public static void SetLocalRotationZ(this Transform transform, float z)
        {
            var v3                     = transform.localEulerAngles;
            v3.z                       = z;
            transform.localEulerAngles = v3;
        }


        public static void SetRelativeLocalRotationX(this Transform transform, float x)
        {
            var v3                     = transform.localEulerAngles;
            v3.x                      += x;
            transform.localEulerAngles = v3;
        }


        public static void SetRelativeLocalRotationY(this Transform transform, float y)
        {
            var v3                     = transform.localEulerAngles;
            v3.y                      += y;
            transform.localEulerAngles = v3;
        }


        public static void SetRelativeLocalRotationZ(this Transform transform, float z)
        {
            var v3                     = transform.localEulerAngles;
            v3.z                      += z;
            transform.localEulerAngles = v3;
        }


        public static void SetAnchoredPositionX(this RectTransform rectTransform, float x)
        {
            var v2                         = rectTransform.anchoredPosition;
            v2.x                           = x;
            rectTransform.anchoredPosition = v2;
        }


        public static void SetAnchoredPositionY(this RectTransform rectTransform, float y)
        {
            var v2                         = rectTransform.anchoredPosition;
            v2.y                           = y;
            rectTransform.anchoredPosition = v2;
        }


        public static void SetAnchoredPositionZ(this RectTransform rectTransform, float z)
        {
            var v3                           = rectTransform.anchoredPosition3D;
            v3.z                             = z;
            rectTransform.anchoredPosition3D = v3;
        }


        public static void SetAnchoredPositionXY(this RectTransform rectTransform, float x, float y)
        {
            rectTransform.anchoredPosition = new Vector2(x, y);
        }


        public static void SetAnchoredPositionXY(this RectTransform rectTransform, float value)
        {
            rectTransform.anchoredPosition = new Vector2(value, value);
        }


        public static void SetAnchoredPosition3D(this RectTransform rectTransform, float value)
        {
            rectTransform.anchoredPosition3D = new Vector3(value, value, value);
        }


        public static void SetRelativeAnchoredPositionX(this RectTransform rectTransform, float x)
        {
            var v2                         = rectTransform.anchoredPosition;
            v2.x                          += x;
            rectTransform.anchoredPosition = v2;
        }


        public static void SetRelativeAnchoredPositionY(this RectTransform rectTransform, float y)
        {
            var v2                         = rectTransform.anchoredPosition;
            v2.y                          += y;
            rectTransform.anchoredPosition = v2;
        }


        public static void SetRelativeAnchoredPositionZ(this RectTransform rectTransform, float z)
        {
            var v3                           = rectTransform.anchoredPosition3D;
            v3.z                            += z;
            rectTransform.anchoredPosition3D = v3;
        }


        public static void SetRelativeAnchoredPositionXY(this RectTransform rectTransform, float x, float y)
        {
            var v2                         = rectTransform.anchoredPosition;
            v2.x                          += x;
            v2.y                          += y;
            rectTransform.anchoredPosition = v2;
        }


        public static void SetRelativeAnchoredPositionXY(this RectTransform rectTransform, in Vector2 v2)
        {
            var pos                        = rectTransform.anchoredPosition;
            pos.x                         += v2.x;
            pos.y                         += v2.y;
            rectTransform.anchoredPosition = pos;
        }


        public static void SetRelativeAnchoredPositionXY(this RectTransform rectTransform, float value)
        {
            var v2                         = rectTransform.anchoredPosition;
            v2.x                          += value;
            v2.y                          += value;
            rectTransform.anchoredPosition = v2;
        }


        public static void SetRelativeAnchoredPositionXY(this RectTransform rectTransform, RectTransform rectTransform2)
        {
            var pos                        = rectTransform .anchoredPosition;
            var v2                         = rectTransform2.anchoredPosition;
            pos.x                         += v2.x;
            pos.y                         += v2.y;
            rectTransform.anchoredPosition = pos;
        }


        public static void SetRelativeAnchoredPosition3D(this RectTransform rectTransform, float value)
        {
            rectTransform.anchoredPosition3D += new Vector3(value, value, value);
        }


        public static void SetOffsetMaxX(this RectTransform rectTransform, float x)
        {                           
            var offsetMax           = rectTransform.offsetMax;
            offsetMax.x             = x;
            rectTransform.offsetMax = offsetMax;
        }


        public static void SetRelativeOffsetMaxX(this RectTransform rectTransform, float x)
        {                           
            var offsetMax           = rectTransform.offsetMax;
            offsetMax.x            += x;
            rectTransform.offsetMax = offsetMax;
        }


        public static void SetOffsetMaxY(this RectTransform rectTransform, float y)
        {                           
            var offsetMax           = rectTransform.offsetMax;
            offsetMax.y             = y;
            rectTransform.offsetMax = offsetMax;
        }


        public static void SetRelativeOffsetMaxY(this RectTransform rectTransform, float y)
        {                           
            var offsetMax           = rectTransform.offsetMax;
            offsetMax.y            += y;
            rectTransform.offsetMax = offsetMax;
        }


        public static void SetRelativeOffsetMax(this RectTransform rectTransform, float x, float y)
        {                           
            rectTransform.offsetMax += new Vector2(x, y);
        }


        public static void SetOffsetMinX(this RectTransform rectTransform, float x)
        {                           
            var offsetMin           = rectTransform.offsetMin;
            offsetMin.x             = x;
            rectTransform.offsetMin = offsetMin;
        }


        public static void SetRelativeOffsetMinX(this RectTransform rectTransform, float x)
        {                           
            var offsetMin           = rectTransform.offsetMin;
            offsetMin.x            += x;
            rectTransform.offsetMin = offsetMin;
        }


        public static void SetOffsetMinY(this RectTransform rectTransform, float y)
        {                           
            var offsetMin           = rectTransform.offsetMin;
            offsetMin.y             = y;
            rectTransform.offsetMin = offsetMin;
        }


        public static void SetSetRelativeOffsetMinY(this RectTransform rectTransform, float y)
        {                           
            var offsetMin           = rectTransform.offsetMin;
            offsetMin.y            += y;
            rectTransform.offsetMin = offsetMin;
        }


        public static void SetSetRelativeOffsetMin(this RectTransform rectTransform, float x, float y)
        {                           
            rectTransform.offsetMin += new Vector2(x, y);
        }
        
        public static void DestroyAllChildren(this Transform transform)
        {
            if (transform.childCount == 0) return;
            for (int i = transform.childCount - 1; i >= 0; i--)
            {
                GameObject.Destroy(transform.GetChild(i).gameObject);
            }
        }

        public static void GetPositionX(this Transform transform, out float x)
        {
            x = transform.position.x;
        }

        public static void GetPositionY(this Transform transform, out float y)
        {
            y = transform.position.y;
        }

        public static void GetPositionZ(this Transform transform, out float z)
        {
            z = transform.position.z;
        }

        public static void GetPosition(this Transform transform, out float x, out float y, out float z)
        {
            x = transform.position.x;
            y = transform.position.y;
            z = transform.position.z;
        }

        public static void GetLocalPositionX(this Transform transform, out float x)
        {
            x = transform.localPosition.x;
        }

        public static void GetLocalPositionY(this Transform transform, out float y)
        {
            y = transform.localPosition.y;
        }

        public static void GetLocalPositionZ(this Transform transform, out float z)
        {
            z = transform.localPosition.z;
        }

        public static void GetLocalPosition(this Transform transform, out float x, out float y, out float z)
        {
            x = transform.localPosition.x;
            y = transform.localPosition.y;
            z = transform.localPosition.z;
        }

        public static void GetRotationX(this Transform transform, out float x)
        {
            x = transform.eulerAngles.x;
        }

        public static void GetRotationY(this Transform transform, out float y)
        {
            y = transform.eulerAngles.y;
        }

        public static void GetRotationZ(this Transform transform, out float z)
        {
            z = transform.eulerAngles.z;
        }

        public static void GetRotation(this Transform transform, out float x, out float y, out float z)
        {
            x = transform.eulerAngles.x;
            y = transform.eulerAngles.y;
            z = transform.eulerAngles.z;
        }

        public static void GetScale(this Transform transform, out float x, out float y, out float z)
        {
            x = transform.localScale.x;
            y = transform.localScale.y;
            z = transform.localScale.z;
        }
    }
}
